package task

import (
	"os"
	"strings"
	"time"

	"gitee.com/sansaniot/ssiot-core/facade/runtime"
	"gitee.com/sansaniot/ssiot-core/logger"
	fileutil "gitee.com/sansaniot/ssiot-core/utils"
	"gorm.io/gorm"

	"ssadmin/common/constant"
	"ssadmin/common/utils"
	"ssadmin/internal/admin/models"
)

// CleanData 清理数据库 (默认保留、按租户设置保留)
func CleanData() {
	db := runtime.Runtime.GetDbByKey("db")
	if db == nil {
		return
	}
	logger.Info("执行数据清理.")
	defaultKeep := constant.DefaultDataKeepDays
	// 按系统配置清理一遍
	clean(db, defaultKeep, "")
	// 按各租户配置的清理
	dkModel := &models.SysDataKeep{}
	dkModel.Orm = db
	keeps := make([]models.SysDataKeep, 0)
	_ = dkModel.FindList(&keeps)
	for _, dataKeep := range keeps {
		clean(db, dataKeep.Keep, dataKeep.AgencyId)
	}
}

func clean(db *gorm.DB, days int, agencyId string) {
	timeLimit := utils.ConvtTimeToStr(time.Now().AddDate(0, 0, -days), utils.TIME_FMT_YMD_000)
	scan := map[string]interface{}{}
	pathList := make([]string, 0)
	snList := make([]string, 0)
	if len(agencyId) > 0 {
		logger.Infof("清理租户%s,时间<%s(%v天以前)的数据", agencyId, timeLimit, days)
		db.Raw("delete from sys_operate_log where operate_time < ? and agency_id = ? ", timeLimit, agencyId).Scan(&scan)
		tmpMapArr := make([]map[string]interface{}, 0)
		db.Raw("select sn from sys_dev where dept_id in (select dept_id from sys_user_dept_r where user_id = ?)", agencyId).Scan(&tmpMapArr)
		for _, m := range tmpMapArr {
			snList = append(snList, m["sn"].(string))
		}
		if len(snList) == 0 {
			return
		}
		db.Raw("delete from sys_alarm where create_time < ? and dev_sn in ? ", timeLimit, snList).Scan(&scan)
		db.Raw("delete from sys_history_system where update_time < ? and dev_sn in ? ", timeLimit, snList).Scan(&scan)
		db.Raw("delete from sys_notify_record where create_time < ? and sn in ? ", timeLimit, snList).Scan(&scan)
		// 查询时间段内的文件
		tmpMapArr = make([]map[string]interface{}, 0)
		db.Raw("select path from sys_resource where create_time < ? and agency_id = ? ", timeLimit, agencyId).Scan(&tmpMapArr)
		for _, m := range tmpMapArr {
			pathList = append(pathList, m["path"].(string))
		}
		db.Raw("delete from sys_resource where create_time < ? and agency_id = ? ", timeLimit, agencyId).Scan(&scan)
	} else {
		logger.Infof("默认清理时间<%s(%v天以前)的数据", timeLimit, days)
		tmpMapArr := make([]map[string]interface{}, 0)
		db.Raw("select sn from sys_dev ").Scan(&tmpMapArr)
		for _, m := range tmpMapArr {
			snList = append(snList, m["sn"].(string))
		}
		db.Raw("delete from sys_alarm where create_time < ? ", timeLimit).Scan(&scan)
		db.Raw("delete from sys_data_detail where create_time < ? ", timeLimit).Scan(&scan)
		db.Raw("delete from sys_history_system where update_time < ? ", timeLimit).Scan(&scan)
		db.Raw("delete from sys_notify_record where create_time < ? ", timeLimit).Scan(&scan)
		db.Raw("delete from sys_operate_log where operate_time < ? ", timeLimit).Scan(&scan)
		// 查询时间段内的文件
		tmpMapArr = make([]map[string]interface{}, 0)
		db.Raw("select path from sys_resource where create_time < ? ", timeLimit).Scan(&tmpMapArr)
		for _, m := range tmpMapArr {
			pathList = append(pathList, m["path"].(string))
		}
		db.Raw("delete from sys_resource where create_time < ? ", timeLimit).Scan(&scan)
	}

	for _, p := range pathList {
		// 删原文件
		_ = os.Remove(constant.FilePath + "/" + p)
		// 删缩略图
		suffix := fileutil.GetExt(p)
		withoutSuffix := strings.ReplaceAll(p, suffix, "")
		thumbnailImagePath := withoutSuffix + constant.ThumbnailConcat + suffix
		_ = os.Remove(constant.FilePath + "/" + thumbnailImagePath)
		logger.Infof("删除文件%v, %v", p, thumbnailImagePath)
	}

	// 历史表删除 兼容分区表、普通表的特性
	db.Raw("select count(1) from pg_stat_activity where state = 'active'").Scan(&scan)
	// 并发过载时不操作  减少压力
	connActiveCount := utils.GetCommUtil().GetIntValueFiled(scan, "count")
	if connActiveCount < 100 && len(snList) > 0 {
		t := time.Now()
		for _, sn := range snList {
			db.Raw("delete from sys_history_sensor where dev_sn = ? and update_time < ? ", sn, timeLimit).Scan(&scan)
		}
		logger.Infof("清理历史数据耗时%v", time.Since(t).Round(time.Millisecond))
	}

}
